/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup Codec
 * @{
 *
 * @brief Codec模块接口定义。
 *
 * Codec模块涉及自定义类型、音视频编解码组件初始化、参数设置、数据的轮转和控制等。
 *
 * @since 3.1
 * @version 2.0
 */

/**
 * @file codec_component_type.h
 *
 * @brief Codec模块接口定义中使用的自定义数据类型。
 *
 * Codec模块接口定义中使用的自定义数据类型，包括编解码类型、音视频参数、buffer定义等。
 *
 * @since 3.1
 * @version 2.0
 */

#ifndef CODEC_COMPONENT_TYPE_H
#define CODEC_COMPONENT_TYPE_H

#include <stdint.h>
#include <stdbool.h>
#include "OMX_Types.h"
#include "OMX_Index.h"
#include "codec_common_type.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */

/**
 * @brief 采样格式最大值。
 */
#define SAMPLE_FMT_NUM 32

/**
 * @brief 定义UUID长度。
 */
#define UUID_LENGTH 128

/**
 * @brief 枚举音视频编解码组件类型。
 */
typedef enum {
    MEDIA_ROLETYPE_IMAGE_JPEG = 0,           /**< 图像JPEG媒体类型。 */
    MEDIA_ROLETYPE_VIDEO_AVC,                /**< 视频H.264媒体类型。 */
    MEDIA_ROLETYPE_VIDEO_HEVC,               /**< 视频H.265媒体类型。 */
    MEDIA_ROLETYPE_AUDIO_FIRST = 0x10000,    /**< 音频编解码器类型。 */
    MEDIA_ROLETYPE_AUDIO_AAC = 0x10000,      /**< 音频AAC媒体类型。 */
    MEDIA_ROLETYPE_AUDIO_G711A,              /**< 音频G711A媒体类型。 */
    MEDIA_ROLETYPE_AUDIO_G711U,              /**< 音频G711U媒体类型。 */
    MEDIA_ROLETYPE_AUDIO_G726,               /**< 音频G726媒体类型。 */
    MEDIA_ROLETYPE_AUDIO_PCM,                /**< 音频PCM媒体类型。 */
    MEDIA_ROLETYPE_AUDIO_MP3,                /**< 音频MP3媒体类型。 */
    MEDIA_ROLETYPE_INVALID,                  /**< 无效媒体类型。 */
} AvCodecRole;

/**
 * @brief 枚举音频采样格式。
 *
 * 对于planar的采样格式，每个声道的数据是独立存储在data中;
 * 对于packed的采样格式，只使用第一个data，每个声道的数据是交错存储的。
 */
typedef enum {
    AUDIO_SAMPLE_FMT_U8,        /**< 无符号8位整型，打包格式。 */
    AUDIO_SAMPLE_FMT_S16,       /**< 带符号16位整型, 打包格式。 */
    AUDIO_SAMPLE_FMT_S32,       /**< 带符号32位整型, 打包格式。 */
    AUDIO_SAMPLE_FMT_FLOAT,     /**< 浮点型, 打包格式。 */
    AUDIO_SAMPLE_FMT_DOUBLE,    /**< 双精度浮点型, 打包格式。 */
    AUDIO_SAMPLE_FMT_U8P,       /**< 无符号8位整型, 平面格式。 */
    AUDIO_SAMPLE_FMT_S16P,      /**< 带符号16位整型, 平面格式。 */
    AUDIO_SAMPLE_FMT_S32P,      /**< 带符号32位整型, 平面格式。 */
    AUDIO_SAMPLE_FMT_FLOATP,    /**< 浮点型, 平面格式。 */
    AUDIO_SAMPLE_FMT_DOUBLEP,   /**< 双精度浮点型, 平面格式。 */
    AUDIO_SAMPLE_FMT_INVALID,   /**< 无效采样格式。 */
} AudioSampleFormat;

/**
 * @brief 支持的像素格式数组大小。
 */
#define PIX_FORMAT_NUM 16

/**
 * @brief 定义视频编解码能力。
 */
typedef struct {
    Rect minSize;                            /**< 支持的最小分辨率。 */
    Rect maxSize;                            /**< 支持的最大分辨率。 */
    Alignment whAlignment;                   /**< 宽高对齐值。 */
    RangeValue blockCount;                   /**< 支持的块数量范围。 */
    RangeValue blocksPerSecond;              /**< 每秒可处理的块数量范围。 */
    Rect blockSize;                          /**< 支持的块大小。 */
    int32_t supportPixFmts[PIX_FORMAT_NUM];  /**< 支持的像素格式，详见{@link OMX_COLOR_FORMATTYPE}。 */
} VideoPortCap;

/**
 * @brief 支持的音频采样格式数组大小。
 */
#define SAMPLE_FORMAT_NUM 12

/**
 * @brief 支持的音频采样率数组大小。
 */
#define SAMPLE_RATE_NUM 16

/**
 * @brief 支持的音频通道数组大小。
 */
#define CHANNEL_NUM 16

/**
 * @brief 定义音频编解码能力。
 */
typedef struct {
    int32_t sampleFormats[SAMPLE_FMT_NUM]; /**< 支持的音频采样格式，详见{@link AudioSampleFormat}。 */
    int32_t sampleRate[SAMPLE_RATE_NUM];   /**< 支持的音频采样率，详见{@link AudioSampleRate}。 */
    int32_t channelLayouts[CHANNEL_NUM];   /**< 支持的音频通道数channel layouts. */
    int32_t channelCount[CHANNEL_NUM];     /**< 支持的音频通道数。*/
} AudioPortCap;

/**
 * @brief 定义音视频编解码能力。
 */
typedef union {
    VideoPortCap video;               /**< 视频编解码能力。 */
    AudioPortCap audio;               /**< 音频编解码能力。 */
} PortCap;

/**
 * @brief 组件名称大小。
 */
#define NAME_LENGTH 32

/**
 * @brief 支持的profile数组大小。
 */
#define PROFILE_NUM 256

/**
 * @brief 定义Codec编解码能力。
 */
typedef struct {
    AvCodecRole role;                     /**< 媒体类型。 */
    CodecType type;                       /**< 编解码类型。 */
    char compName[NAME_LENGTH];           /**< 编解码组件名称。 */
    int32_t supportProfiles[PROFILE_NUM]; /**< 支持的profiles，详见{@link Profile}。 */
    int32_t maxInst;                      /**< 最大实例。 */
    bool isSoftwareCodec;                 /**< 软件编解码还是硬件编解码。 */
    int32_t processModeMask;              /**< 编解码处理模式掩码，详见{@link CodecProcessMode}。 */
    uint32_t capsMask;                    /**< 编解码播放能力掩码，详见{@link CodecCapsMask}。 */
    RangeValue bitRate;                   /**< 支持的码率范围。 */
    PortCap port;                         /**< 支持的音视频编解码能力。 */
} CodecCompCapability;

/**
 * @brief 定义buffer类型。
 */
enum CodecBufferType {
    CODEC_BUFFER_TYPE_INVALID = 0,             /**< 无效buffer类型。 */
    CODEC_BUFFER_TYPE_VIRTUAL_ADDR = 0x1,      /**< 虚拟地址类型。 */
    CODEC_BUFFER_TYPE_AVSHARE_MEM_FD = 0x2,    /**< 共享内存类型。 */
    CODEC_BUFFER_TYPE_HANDLE = 0x4,            /**< handle类型。 */
    CODEC_BUFFER_TYPE_DYNAMIC_HANDLE = 0x8,    /**< 动态handle类型。 */
};

/**
 * @brief 枚举共享内存类型。
 */
enum ShareMemTypes {
    READ_WRITE_TYPE = 0x1,   /**< 可读可写的共享内存类型。 */
    READ_ONLY_TYPE = 0x2,    /**< 可读的共享内存类型。 */
};

/**
 * @brief Codec buffer信息的定义。
 */
struct OmxCodecBuffer {
    uint32_t bufferId;               /**< buffer ID。 */
    uint32_t size;                   /**< 结构体大小。 */
    union OMX_VERSIONTYPE version;   /**< 组件版本信息。 */
    enum CodecBufferType bufferType; /**< buffer类型。 */
    uint8_t *buffer;                 /**< 编码或者解码使用的buffer。 */
    uint32_t bufferLen;              /**< buffer大小。 */
    uint32_t allocLen;               /**< 申请的buffer大小。 */
    uint32_t filledLen;              /**< 填充的buffer大小。 */
    uint32_t offset;                 /**< 有效数据从缓冲区开始的起始偏移量。 */
    int32_t fenceFd;                 /**< 该描述符来自buffer消费者，Codec等待成功后才可以使用输入或者输出buffer。 */
    enum ShareMemTypes type;         /**< 共享内存类型。 */
    int64_t pts;                     /**< 时间戳。 */
    uint32_t flag;                   /**< 标志。 */
};

/**
 * @brief 枚举Codec扩展index。
 */
enum OmxIndexCodecExType {
    OMX_IndexExtBufferTypeStartUnused = OMX_IndexKhronosExtensions + 0x00a00000, /**< BufferType 扩展index。 */
    OMX_IndexParamSupportBufferType,                                             /**< SupportBuffer类型。 */
    OMX_IndexParamUseBufferType,                                                 /**< UseBuffer类型。 */
    OMX_IndexParamGetBufferHandleUsage,                                          /**< GetBufferHandleUsage类型。 */
};

/**
 * @brief 枚举Codec扩展编码类型。
 */
enum OmxVideoExType {
    OMX_VIDEO_CodingHEVC = 11,  /**< HEVC编码类型。 */
};

/**
 * @brief 定义组件版本信息。
 */
struct CompVerInfo {
    char compName[NAME_LENGTH];         /**< 组件名称。 */
    uint8_t compUUID[UUID_LENGTH];      /**< 组件的UUID标识符。 */
    union OMX_VERSIONTYPE compVersion;  /**< OMX组件版本信息。 */
    union OMX_VERSIONTYPE specVersion;  /**< 构建组件所依据的规范的版本信息。 */
};

/**
 * @brief 定义事件上报信息。
 */
struct EventInfo {
    int8_t *appData;                /**< 设置回调时给入的上层实例。 */
    uint32_t appDataLen;            /**< appData字节数。 */
    uint32_t data1;                 /**< 事件上报携带的数据1。 */
    uint32_t data2;                 /**< 事件上报携带的数据2。 */
    int8_t *eventData;              /**< 事件上报携带的数据信息。 */
    uint32_t eventDataLen;          /**< eventData字节数。 */
};

/**
 * @brief SupportBuffer类型定义。
 */
struct SupportBufferType {
    uint32_t size;                                          /**< 结构体大小。 */
    union OMX_VERSIONTYPE version;                          /**< 组件版本信息。 */
    uint32_t portIndex;                                     /**< 端口索引。 */
    uint32_t bufferTypes;                                   /**< 支持的所有Buffer类型。 */
};

/**
 * @brief UseBuffer类型定义。
 */
struct UseBufferType {
    uint32_t size;                                         /**< 结构体大小。 */
    union OMX_VERSIONTYPE version;                         /**< 组件版本信息。 */
    uint32_t portIndex;                                    /**< 端口索引。 */
    uint32_t bufferType;                                   /**< Buffer类型。 */
};

/**
 * @brief BufferHandleUsage类型定义。
 */
struct GetBufferHandleUsageParams {
    uint32_t size;                                         /**< 结构体大小。 */
    union OMX_VERSIONTYPE version;                         /**< 组件版本信息。 */
    uint32_t portIndex;                                    /**< 端口索引。 */
    uint32_t usage;                                        /**< 申请内存的使用场景。 */
};

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

#endif /* CODEC_COMPONENT_TYPE_H */
/** @} */